/*

    real entities - a queriable text db

    Copyright (C) 2009 Eugeny Yakimovitch (at) gmail dot com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.    
    
*/

#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1

#include "entity.h"
#include "utils.h"

#include <fstream>
#include <cryptopp/md5.h>
#include <cryptopp/filters.h>
#include <cryptopp/files.h>
#include <cryptopp/hex.h>

namespace crw = CryptoPP::Weak;
namespace fs = boost::filesystem;

rea::entity::entity ()
{

}

rea::entity::entity (const fs::path &path)
{
  
}

rea::entity::~entity ()
{

}

void
rea::entity::md5digest (const char *path, char *result)
{
  crw::MD5 hash;
  byte buffer[2 * crw::MD5::DIGESTSIZE];	//output size of the buffer

  CryptoPP::FileSource f (path, true,
			  new CryptoPP::HashFilter (hash,
						    new CryptoPP::
						    HexEncoder (new CryptoPP::
								ArraySink
								(buffer,
								 2 *
								 crw::MD5::
								 DIGESTSIZE))),
			  false);
  strcpy (result, (const char *) buffer);
}

void
rea::entity::md5digest (const fs::path &path, std::string & result)
{
  char buffer[2 * crw::MD5::DIGESTSIZE];
  this->md5digest (path.file_string().c_str(), (char *) &buffer);
  result = buffer;
}


void
rea::entity::parse (const char *c_str_path)
{
  fs::path path(c_str_path);
  this->parse(path);
}
void
rea::entity::parse (const fs::path &path)
{  
  std::ifstream fs (path.file_string().c_str(), std::ifstream::in);
  std::string str, key, value;
  char s[entity::MAX_VALUE_SIZE];
  int pos;

  while (fs.good ())
    {
      fs.getline (s, entity::MAX_VALUE_SIZE);
      str = s;
      if (str.empty ())
	continue;
      pos = 0;
      pos = str.find (':', pos);
      key = str.substr (0, pos);
      trim_string (key);
      value = str.substr (pos + 1);
      trim_string (value);      
      this->pairs[key] = value;
    }
  fs.close ();
  // add hash key-value pair
  this->md5digest (path, value);
  this->pairs[HASH_KEY_STR] = value;
}

void
rea::entity::write (const  char *c_str_path)
{
  fs::path path(c_str_path);
  this->write(path);
}
void
rea::entity::write (const fs::path &path)
{
  std::ofstream fs (path.file_string().c_str(), std::ofstream::out);
  std::map < std::string, std::string >::iterator it;

  for (it = this->pairs.begin (); it != this->pairs.end (); it++)
    fs << (*it).first << ": " << (*it).second << std::endl;

  fs.close ();
}
